package me.shiqiang.im.service;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.SendResult;
import com.fasterxml.jackson.core.JsonProcessingException;
import me.shiqiang.im.msg.MsgBody;
import me.shiqiang.im.msg.NewMsg;
import me.shiqiang.im.redis.RedisKey;
import me.shiqiang.im.utils.JsonUtils;
import me.shiqiang.im.vo.GroupUser;
import me.shiqiang.im.vo.ZSetVo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * @author cuishiqiang
 * @date 2017/12/9 下午3:37
 */
//@Service
//@CacheConfig(cacheNames = "groupUsers")
public class MsgService {
    private Logger logger = LoggerFactory.getLogger(MsgService.class);

    @Autowired
    StringRedisTemplate redisTemplate;


    @Autowired
    Producer producer;

    @Value("${send.topic}")
    String topic;


    @Autowired
    GroupClient groupClient;

    @Value("business.server.id")
    String serverId;

    @Autowired
    ServerNodeClient serverNodeClient;

    public String popMsg(String key) {
        return redisTemplate.opsForList().leftPop(key, 60, TimeUnit.SECONDS);
    }

    public void pushMsg(String key, String value) {
        redisTemplate.opsForList().rightPush(key, value);
    }

    public Long getMsgSyncKey() {
        return redisTemplate.opsForValue().increment(RedisKey.SYNC_KEY, 1);
    }

    @Cacheable(key = "'user.serverId:'+#userId")
    public String getServerId(Long userId){
        return serverNodeClient.getServerId(userId.toString());
    }


    @Cacheable(key = "#groupId")
    public Collection<GroupUser> getGroupUser(Long groupId) {
        return groupClient.getGroupUsers(groupId).getRes();
    }

    public void addToUserMsgQueue(Long userId, String json, Long syncKey) {
        redisTemplate.opsForZSet().add(RedisKey.clientMsgQueue(userId.toString()), json, syncKey);
        logger.info("用户{}队列添加信息：{},syncKey:{}", userId, json, syncKey);
    }

    public void addToUserMsgQueue(List<ZSetVo> list) {
        redisTemplate.executePipelined((RedisCallback<Long>) connection -> {
            for (ZSetVo vo : list) {
                connection.zAdd(vo.getKey().getBytes(), vo.getScore(), vo.getValue().getBytes());
            }
            return null;
        });
    }

    public void addToGroupMsgQueue(Long groupId, String json, Long syncKey) {
        redisTemplate.opsForZSet().add(RedisKey.clientMsgQueue(groupId.toString()), json, syncKey);
        logger.info("群{}队列添加信息：{},syncKey:{}", groupId, json, syncKey);
    }

    public void notifyUser(Long userId, String msgEvent, MsgBody msgBody) throws JsonProcessingException {
        NewMsg fromNewMsg = new NewMsg(msgBody.getMsg(), userId, msgBody.getSyncKey());

        String s = JsonUtils.getInstance().toJson(fromNewMsg);
        Message from = new Message(topic, userId.toString(), msgEvent, s.getBytes());
//        producer.sendOneway(from);
//        SendResult fromResult = producer.send(from);
//        assert fromResult != null;
    }

    public void notifyUser(Long userId, MsgBody msgBody) throws JsonProcessingException {
        NewMsg fromNewMsg = new NewMsg(msgBody.getMsg(), userId, msgBody.getSyncKey());

        String s = JsonUtils.getInstance().toJson(fromNewMsg);
        Message from = new Message(topic, userId.toString(), s.getBytes());
        SendResult fromResult = producer.send(from);
        assert fromResult != null;
    }

    public void returnToUser(Long userId, Object msg) throws JsonProcessingException {

        String s = JsonUtils.getInstance().toJson(msg);
        Message from = new Message(topic, userId.toString(), s.getBytes());
        SendResult fromResult = producer.send(from);
        assert fromResult != null;
    }

    public void getServerUsers() {

    }
}
